import { Injectable, EventEmitter } from '@angular/core';
import { GanttModel, PredecessorLinkModel } from './gantt.model';
import { NzNotificationService, NzMessageService, NzModalService } from 'ng-zorro-antd';
import * as moment from 'moment';
import { Component, enableProdMode } from '@angular/core';
import { RequestClientService } from '../request-client.service';
import { SERVERURL } from '../../config';
import { ActivatedRoute } from '@angular/router';
import { GanttApi } from './gantt.api';
import { ModelService } from '../model/model.service';

import { UInfoModel } from './uuid.model';
import { ProgressModel } from './progress.model';
import { ProjectService } from '../project/project.service';
import { PREVTYPE, EXTENDATTRS } from './gantt.config';
import { GanttProjectModel, ITask } from './gantt-project.model';
import { GanttRequestService } from './gantt-request.service';

declare var Neon: any;
interface bindingsControll {
  // 显示追加构件button
  addFragmentShow: boolean;
  // 显示绑定构件button
  addBindingsShow: boolean;
  // 显示解绑构件button
  removeBindsShow: boolean;
}
class ExceptDateModel {
  public name: string;
  public startDate: any;
  public endDate: any;
  public constructor(param?: any) {
    (param.name) && (this.name = param.name);
    (param.startDate) && (this.startDate = param.startDate);
    (param.endDate) && (this.endDate = param.endDate);
  }
  public toMoment() {
    return {
      name: this.name,
      startDate: moment.unix(this.startDate),
      endDate: moment.unix(this.endDate)
    };
  }
}
@Injectable()
export class GanttService {
  public bottomHeight = 300;
  // 创建gantt项目
  public newGanttModalView = false;
  public currentGantt: GanttProjectModel;
  public ganttList: Array<GanttProjectModel> = [];

  public allTasks: Array<GanttModel> = [];  //所有task
  public showTask: any = []; //显示区task数组
  public hideTasksId: any = []; //折叠隐藏的task的Index数组
  public taskShowLength: number;  //显示区task数组长度
  public canvasHeight = 0;
  public starIndex = 0;  //显示区task开始的位置
  public endIndex: number;
  public canvasInfo: any = [];
  public exceptCanvasInfo: any = [];
  public actualCanvasInfo: any = [];
  public calenderWidth: number;
  public weeksArry: any = [];
  public minLineDay: any;
  // relationsInfo: any = [];
  public taskHeight = 36;
  public showKeyLine = false;
  public alreadyDeleteTasks: any = []; // 传id
  public alreadyAddTasks: any = []; // 传 对象
  public alreadyEditTasks: any = []; //传id
  public addTaskList: string;
  public getTaskList: string;
  public updateTaskList: string;
  public deleteTaskList: string;
  public ganttChartId = '';
  public ganttStep: any = 0;
  public IsAllSelected = false;
  public stepStore: any = [];
  public uuidMap: any = new Map;
  public getTaskListFromParent = false;
  // 提交保存的loading
  public loading = false;
  public bindingsControll: bindingsControll = {
    // 显示追加构件button
    addFragmentShow: false,
    // 显示绑定构件button
    addBindingsShow: true,
    // 显示解绑构件button
    removeBindsShow: false
  };
  public baseWidth = 25; // 日历的单位宽度

  public currentTask: GanttModel;
  public exceptDate: any = [];
  public showKeyTask = false;
  public settingVisible = false;

  public maxUID = 0;

  public maskInfo: {
    showLoading: boolean,
    showWarnning: boolean
  } = {
      showLoading: false,
      showWarnning: false
    };
  public detailView = false;

  public constructor(
    private _notification: NzNotificationService,
    private _message: NzMessageService,
    private requestClientService: RequestClientService,
    private activatedRoute: ActivatedRoute,
    private confirmServ: NzModalService,
    private ganttApi: GanttApi,
    private modelService: ModelService,
    private projectService: ProjectService,
    private ganttRequestSev: GanttRequestService
  ) {
    this.addTaskList = SERVERURL + 'api/task/commonOperation';
    this.getTaskList = SERVERURL + 'api/task/getlist';
    this.updateTaskList = SERVERURL + 'api/task/updatelist';
    this.deleteTaskList = SERVERURL + 'api/task/delete';
    this.activatedRoute.queryParams.subscribe(
      (queryParams: any) => {
        if (queryParams.id) {
          console.log(`gantt step is ${this.ganttStep}`);
          if (queryParams.id == 'init') {
            this.allTasks = [];
            this.canvasInfo = [];
            this.actualCanvasInfo = [];
            this.weeksArry = [];
            setTimeout(() => {
              this.showTask = [];
            }, 500);
            this.currentGantt = new GanttProjectModel({
              title: '请选择一个进度项目',
              calendars: []
            });
            console.log('init uuidMap');
            this.ganttApi.init(this.uuidMap);
            this.maskInfo.showWarnning = true;
          } else {
            this.ganttApi.init(this.uuidMap);
            this.initTasks(queryParams.id);
            this.maskInfo.showWarnning = false;

          }
        }
      }
    );
  }

  public async initTasks(ganttId: string) {
    let taskList = await this.ganttRequestSev.getTasksList(ganttId);
    let gantt = await this.ganttRequestSev.getGanttInfo(ganttId);
    let extendAttrs = await this.ganttRequestSev.getGanttAttrs(ganttId);
    let finder = extendAttrs.find((attr) => {
      return attr.fieldID == EXTENDATTRS.binding.FieldID;
    });
    this.currentGantt = new GanttProjectModel({
      id: gantt.id,
      calendars: [],
      title: gantt.title,
      parentId: gantt.parentId,
      creationDate: gantt.creationDate
    });
    if (!finder) {
      let res = await this.ganttRequestSev.postGanttBindingAttr(ganttId);
      if (res.success) {
        this._message.success('资源创建成功');
        this.currentGantt.bindingInfo = {
          num: EXTENDATTRS.binding.FieldID,
          Id: res.data.id
        };
        // this.dealWithMPP(taskList);
      } else {
        // this._message.error('资源创建失败');
      }
      this.dealWithMPP(taskList);
    } else {
      this._message.success('资源已绑定');
      this.currentGantt.bindingInfo = {
        num: EXTENDATTRS.binding.FieldID,
        Id: finder.id
      };
      this.dealWithMPP(taskList);
    }
    //默认创建一条子任务
    console.log("生成了一个子任务：gantt.service.ts.initTasks.addTaskHandle")
    this.addTaskHandle('addNewTask')
    this.detailView = false;
    console.log(this.currentGantt);
  }

  /**
   * 新建进度
   * @param param
   */
  public addNewProgress(param: ProgressModel) {
    console.log(param.toCreateJson());
    return this.requestClientService.post(SERVERURL + 'api/gantt/add', param.toCreateJson()).then((res) => {
      console.log(res);
      return res;
    });
  }

  /**
   * 处理mpp
   * @param mppTasks 
   */
  public dealWithMPP(mppTasks: ITask[]) {
    console.log(mppTasks);
    let allTasks = [];
    let maxUID = 0;
    let findBindings = (ExtendedAttribute) => {
      let finder = ExtendedAttribute.find((attr) => {
        return attr.fieldID == EXTENDATTRS.binding.FieldID;
      });
      if (finder) {
        return JSON.parse(finder.value);
      } else {
        return [];
      }
    };
    mppTasks.forEach((element, index) => {
      if (element._ID) {
        let symbol = index + 1000;
        let bindings = findBindings(element.extendedAttribute);
        let defaultData = {
          sqId: element.id,
          // exceptDate: this.exceptDate ? this.exceptDate : [],
          uid: element.uid,
          id: element._ID,
          symbol,
          wbs: element.wbs,
          taskName: element.name,
          startDate: element.start ? moment(element.start).toDate() : null,
          duration: 0,
          endDate: element.finish ? moment(element.finish).toDate() : null,
          actualStartDate: element.actualStart ? moment(element.actualStart).toDate() : null,
          actualDuration: 0,
          actualEndDate: element.actualFinish ? moment(element.actualFinish).toDate() : null,
          childTaskID: this.WBS2ParentId(element, mppTasks).childId,
          parentTaskID: this.WBS2ParentId(element, mppTasks).parentId,
          level: this.WBS2ParentId(element, mppTasks).level,
          isMilepost: element.milestone,
          prevRelation: this.dealWithPrev(element, mppTasks),
          bindings,
          ganttChartId: element.parentId
        };
        let task = new GanttModel(defaultData);
        task.defaultData = defaultData;
        allTasks.push(task);
        if (bindings && bindings.length > 0) {
          this.uuidMap.set(symbol, bindings);
        }
      }
      if (element.uid > maxUID) {
        this.maxUID = element.uid;
      }
    });
    this.allTasks = allTasks;
    this.ganttApi.init(this.uuidMap);
    console.log(this.allTasks);
    this.updateAllTaskInfo();
  }



  /**
   * 处理PredecessorLink
   * @param task 
   * @param allTasks 
   */
  public dealWithPrev(task: ITask, allTasks: ITask[]) {
    // debugger;
    let PredecessorLink = task.predecessorLink;
    let preTask = [];
    let finderId = (PredecessorUID) => {
      let finder = allTasks.find((ele) => {
        return ele.uid == PredecessorUID;
      });
      if (finder)
        return finder._ID;
    };
    if (PredecessorLink && PredecessorLink.length > 0) {
      PredecessorLink.forEach((element) => {
        let prevTask = new PredecessorLinkModel({
          prevId: finderId(element.predecessorUID),
          relation: element.type,
          delay: element.linkLag ? element.linkLag / 600 / 8 : 0,
          id: element.id,
          defaultPrev: element
        });
        preTask.push(prevTask);
      });
    }
    return preTask;
  }

  /**
   * WBS转可读数组
   * @param task 
   * @param allTasks 
   */
  public WBS2ParentId(task: ITask, allTasks: ITask[]) {
    let level = 1;
    let findParentId = (task: ITask) => {
      let array = task.wbs.split('.');
      level = array.length;
      if (array.length == 1) {
        return null;
      }
      array.pop();
      let newStr = array.join('.');
      let finder = allTasks.find((element) => {
        return element.wbs == newStr;
      });
      if (finder) {
        return finder._ID;
      } else {
        return null;
      }
    };

    let childId = [];
    let findChildId = (task: ITask) => {
      for (let i = parseInt(task._ID.toString()); i < allTasks.length; i++) {
        const element = allTasks[i];
        let array = element.wbs.split('.');
        array.pop();
        let newStr = array.join('.');
        if (newStr == task.wbs) {
          childId.push(element._ID);
        }
      }
    };
    findChildId(task);

    return {
      parentId: findParentId(task),
      childId,
      level
    };
  }


  // 确认提示框
  public showConfirm = () => {
    let that = this;
    this.confirmServ.confirm({
      nzTitle: '是否要删除选中任务及其所有的子任务？？',
      nzContent: '点击确认将删除选中任务及其所有的子任务，点击取消将不删除任何任务。',
      nzOnOk() {
        that.deleteTaskHandle();
      }
    });
  }

  // 错误提示框
  public createNotification = (type: string, message: string, size: string, title?: string) => {
    if (size == 'large') {
      this._notification.create(type, title, message);
    } else if (size == 'small') {
      this._message.create(type, message, { nzDuration: 2000 });
    }
  }


  public updateAllTaskInfo(isFromStore?: boolean) {
    // 清空canvas
    this.canvasInfo = [];
    this.actualCanvasInfo = [];
    if (this.allTasks.length > 0) {
      // 更新showTask
      this.updateTaskHandle();
      // 更新ChildTaskID 和 ParentTaskID
      this.updateLeveInfo();
      // 生成relationsInfo数组
      // this.getPrevTaskInfo();


      // 根据前置任务的时间更新startDate
      this.updateStartDate();
      // 更新parent的startDate
      this.updateParentStartDate();
      // 计算showDuration
      this.dealWithExceptDate();


      // 更新startDate
      // this.updateActualStartDate();
      // 更新parent的actualStartDate
      // this.updateParentActualStartDate();
      // 计算showDuration
      // this.dealWithActualExceptDate()


      // 最后更新 canvas和日历(update canvas)
      this.updateCanvasInfo();
    } else {
      this.showTask = [];
      this.weeksArry = [];
    }
  }

  /**
   * 计算showDuration
   */
  public dealWithExceptDate() {
    let allTasks = this.allTasks;
    for (let i = 0; i < allTasks.length; i++) {
      const task = allTasks[i];
      let startUnix2 = task.startDate ? moment(task.startDate).unix() : null;
      let endUnix2 = task.endDate ? moment(task.endDate).unix() : null;
      let allExcept = 0;
      // 再统计任务中所有的例外日期工期
      this.exceptDate.forEach((item) => {
        // 例外日期在任务的开始时间和结束时间之间
        if (startUnix2 <= item.startDate && endUnix2 >= item.endDate) {
          let exceptDuration = moment.unix(item.endDate).clone().diff(moment.unix(item.startDate), 'days') + 1;
          allExcept = allExcept + exceptDuration;
        }
      });
      allTasks[i].exceptDuration = allExcept;
      // 计算showDuration
      if (task.duration) {
        task.showDuration = task.duration - allExcept;
      } else {
        if (task.startDate && task.endDate) {
          let num = moment(task.endDate).clone().diff(moment(task.startDate), 'days');
          task.showDuration = num + 1;
        }
      }
    }
  }

  /**
   * 计算实际showDuration
   */
  public dealWithActualExceptDate() {
    let allTasks = this.allTasks;
    for (let i = 0; i < allTasks.length; i++) {
      const task = allTasks[i];
      let startUnix2 = task.actualStartDate ? moment(task.actualStartDate).unix() : null;
      let endUnix2 = task.actualEndDate ? moment(task.actualEndDate).unix() : null;
      let allExcept = 0;
      // 再统计任务中所有的例外日期工期
      this.exceptDate.forEach((item) => {
        // 例外日期在任务的开始时间和结束时间之间
        if (startUnix2 <= item.startDate && endUnix2 >= item.endDate) {
          let exceptDuration = moment.unix(item.endDate).clone().diff(moment.unix(item.startDate), 'days') + 1;
          allExcept = allExcept + exceptDuration;
        }
      });
      task.exceptActualDuration = allExcept;
      // 计算showDuration
      if (task.actualDuration) {
        task.showActualDuration = task.actualDuration - allExcept;
      } else {
        if (task.actualStartDate && task.actualEndDate) {
          let num = moment(task.actualEndDate).clone().diff(moment(task.actualStartDate), 'days');
          task.showActualDuration = num + 1;
        }
      }
    }
  }

  /*
  * 更新canvasInfo
  * major function
  */
  public updateCanvasInfo = () => {
    let allTasks = this.allTasks;
    let calenderArry = [];
    let lastFinishTask = 0;
    let lastActualFinishTask = 0;
    let lastFinishDay = allTasks[0].endDate;
    let lastActualFinishDay = allTasks[0].actualEndDate;
    let baseWidth = this.baseWidth;
    for (let i = 0; i < allTasks.length; i++) {
      let endDate = allTasks[i].endDate;
      let startDate = allTasks[i].startDate;
      let actualEndDate = allTasks[i].actualEndDate;
      let actualStartDate = allTasks[i].actualStartDate;
      if (endDate && startDate) {
        calenderArry.push(moment(allTasks[i].startDate));
        calenderArry.push(moment(allTasks[i].endDate));
        if (moment(endDate).clone().diff(moment(lastFinishDay), 'days') >= 0) {
          // 找到日期最后一天对应的任务id
          lastFinishTask = allTasks[i].id;
          lastFinishDay = allTasks[i].endDate;
        }
      }
      if (actualEndDate && actualStartDate) {
        calenderArry.push(moment(allTasks[i].actualStartDate));
        calenderArry.push(moment(allTasks[i].actualEndDate));
        if (!lastActualFinishDay) {
          lastActualFinishDay = actualEndDate;
        } else {
          if (moment(actualEndDate).clone().diff(moment(lastActualFinishDay), 'days') >= 0) {
            // 找到日期最后一天对应的任务id
            lastActualFinishTask = allTasks[i].id;
            lastActualFinishDay = allTasks[i].actualEndDate;
          }
        }
      }
    }
    // showTask最早开始/最晚结束日期/之间的周数
    let minDay = moment.min(calenderArry).clone();
    let maxDay = moment.max(calenderArry).clone();

    // 第一周周日，即坐标开始
    let minLineDay = minDay.subtract(minDay.day(), 'days');
    // 最后一周周日
    let maxLineDay = maxDay.subtract(maxDay.day(), 'days').day(7);

    //计算每周日数组
    let weekCount = maxLineDay.clone().diff(minLineDay.clone(), 'weeks');
    let weeksArry = [];
    for (let i = 0; i < weekCount; i++) {
      let aa = minLineDay.clone().day(7 * i).format('YYYY-MM-DD');
      weeksArry.push(aa);
    }
    if (calenderArry.length == 0) {
      this.calenderWidth = 0;
    } else {
      this.weeksArry = weeksArry;
      this.calenderWidth = weeksArry.length * 7 * baseWidth;
    }

    // 计算计划时间的关键线路
    if (lastFinishTask) {
      // 清空关键线路
      this.cleanKeyLoop(allTasks);
      // 重新计算关键线路
      this.findKeyLoop(allTasks, lastFinishTask);
    }
    // 计算canvasInfo
    this.positionCalculate(minLineDay);


    // 计算 actualCanvasInfo
    if (lastActualFinishTask) {
      this.cleanActualKeyLoop(allTasks);
      this.findActualKeyLoop(allTasks, lastActualFinishTask);
    }
    this.positionActualCalculate(minLineDay);
    this.minLineDay = minLineDay;
  }

  /*
  * private for updateCanvasInfo
  */
  public positionCalculate = (minLineDay) => {
    // 默认画轴起点坐标（0，0）
    // let tasks = this.showTask;
    let tasks = this.allTasks;
    let canvasInfo = [];
    let baseWidth = this.baseWidth;
    // 计算
    for (let i = 0; i < tasks.length; i++) {
      let startDate = moment(tasks[i].startDate);
      let endDate = moment(tasks[i].endDate);
      let duration = tasks[i].duration;
      let isKey = tasks[i].isKey;
      let IsSelected = tasks[i].IsSelected;
      let childTaskID = tasks[i].childTaskID;
      let type;
      let isMilepost = tasks[i].isMilepost;
      // 找出task[i]之前fold的task个数
      let foldBefore = [];
      this.hideTasksId.forEach((element) => {
        if (element < i + 1) {
          foldBefore.push(element);
        }
      });

      let width: number;
      if (isMilepost && duration == 1) {
        type = 'milepost';
      } else if (childTaskID.length > 0) {
        type = 'parentType';
      }
      // 里程碑width为0
      if (isMilepost && duration == 1) {
        width = 0;
      } else {
        width = (endDate.diff(startDate, 'days') + 1) * baseWidth;
      }
      canvasInfo.push({
        // task起点x坐标
        positionX: startDate.clone().diff(moment(minLineDay).clone(), 'days') * baseWidth,
        // task起点y坐标
        positionY: this.taskHeight * i + 5 - this.starIndex * this.taskHeight - foldBefore.length * this.taskHeight,
        // positionY: this.taskHeight * i + 10,
        // 根据工期算出来的task宽度
        width,
        // 横道图颜色
        color: isKey ? 'rgba(254,128,1,1)' : 'rgba(45,189,197,1)',
        // 是否是关键任务
        isKey,
        // 图形样式
        type,
        // 是否选中
        IsSelected
      });
    }
    let exceptDate = this.currentGantt.calendars;
    let exceptCanvasInfo = [];
    exceptDate.forEach((element) => {
      let positionX = moment(element.startDate).clone().diff(moment(minLineDay).clone(), 'days') * baseWidth;
      let width = (moment(element.endDate).diff(moment(element.startDate), 'days') + 1) * baseWidth;
      exceptCanvasInfo.push({
        positionX,
        width
      });
    });
    this.exceptCanvasInfo = exceptCanvasInfo;
    this.canvasInfo = canvasInfo;
  }

  public positionActualCalculate = (minLineDay) => {
    // 默认画轴起点坐标（0，0）
    // let tasks = this.showTask;
    let tasks = this.allTasks;
    let canvasInfo = [];
    let baseWidth = this.baseWidth;
    // 计算
    for (let i = 0; i < tasks.length; i++) {
      let startDate = moment(tasks[i].actualStartDate);
      let endDate = moment(tasks[i].actualEndDate);
      let duration = tasks[i].actualDuration;
      // let isKey = tasks[i].isActualKey;
      let isKey = tasks[i].isKey;
      let IsSelected = tasks[i].IsSelected;
      let childTaskID = tasks[i].childTaskID;
      let type;
      let isMilepost = tasks[i].isMilepost;
      // 找出task[i]之前fold的task个数
      let foldBefore = [];
      this.hideTasksId.forEach((element) => {
        if (element < i + 1) {
          foldBefore.push(element);
        }
      });

      let width: number;
      if (isMilepost && duration == 0) {
        type = 'milepost';
      } else if (childTaskID.length > 0) {
        type = 'parentType';
      }
      // 里程碑width为0
      if (isMilepost && duration == 0) {
        width = 0;
      } else {
        width = (endDate.diff(startDate, 'days') + 1) * baseWidth;
      }

      canvasInfo.push({
        // task起点x坐标
        positionX: startDate.clone().diff(moment(minLineDay).clone(), 'days') * baseWidth,
        // task起点y坐标
        positionY: this.taskHeight * i + 13 - this.starIndex * this.taskHeight - foldBefore.length * this.taskHeight,
        // positionY: this.taskHeight * i + 10,
        // 根据工期算出来的task宽度
        width,
        // 横道图颜色
        color: isKey ? '#e74b8f' : '#419fe8',
        // 是否是关键任务
        isKey,
        // 图形样式
        type,
        // 是否选中
        IsSelected
      });
    }
    this.actualCanvasInfo = canvasInfo;
  }

  // 循环查找关键线路
  public findKeyLoop = (tasks: Array<GanttModel>, key: number) => {
    tasks[key - 1].isKey = true;
    if (tasks[key - 1].childTaskID.length > 0) {
      let childTaskID = tasks[key - 1].childTaskID;
      let allTasks = this.allTasks;
      childTaskID.forEach((id) => {
        if (allTasks[id - 1].endDate == tasks[key - 1].endDate) {
          allTasks[id - 1].isKey = true;
        }
      });
    }
    let keyWork = tasks[key - 1].truePrevTaskID;
    if (keyWork) {
      this.findKeyLoop(tasks, keyWork);
    } else {
      return;
    }
  }

  // 循环查找关键线路
  public findActualKeyLoop = (tasks: Array<GanttModel>, key: number) => {
    tasks[key - 1].isActualKey = true;
    let keyWork = tasks[key - 1].actulaTruePrevTaskID;
    if (keyWork) {
      this.findActualKeyLoop(tasks, keyWork);
    } else {
      return;
    }
  }

  // 初始化关键线路isKey = false
  public cleanKeyLoop = (tasks: Array<GanttModel>) => {
    for (let i = 0; i < tasks.length; i++) {
      let element = tasks[i];
      element.isKey = false;
    }
  }

  public cleanActualKeyLoop(tasks: Array<GanttModel>) {
    for (let i = 0; i < tasks.length; i++) {
      let element = tasks[i];
      element.isActualKey = false;
    }
  }

  // getPrevTaskInfo() {
  //   let allTasks = this.allTasks;
  //   let relationsInfo = [];
  //   for (let i = 0; i < allTasks.length; i++) {
  //     if (allTasks[i].prevRelation && allTasks[i].prevRelation.length > 0) {
  //       // relationsInfo[i] = allTasks[i].prevRelation;
  //       relationsInfo[i] = [];
  //       allTasks[i].prevRelation.forEach(res => {
  //         if (!res.isDelete) {
  //           relationsInfo[i].push(res)
  //         }
  //       })
  //     } else {
  //       relationsInfo[i] = []
  //     }
  //   }
  //   this.relationsInfo = relationsInfo;
  //   console.log(relationsInfo)
  // }

  /*
  *  循环所有摘要里的prevRelation
  */
  public parentLoop = (ownPrevRelation: GanttModel['prevRelation'], currentTask: GanttModel) => {
    let parentIndex = currentTask.parentTaskID - 1;
    let parentPrev = this.allTasks[parentIndex].prevRelation;
    let allTasks = this.allTasks;
    for (let p = 0; p < parentPrev.length; p++) {
      let prev = parentPrev[p];
      if (ownPrevRelation.indexOf(prev) == -1) {
        ownPrevRelation.push(prev);
      }
    }
    if (allTasks[parentIndex].parentTaskID) {
      this.parentLoop(ownPrevRelation, allTasks[parentIndex]);
    }
  }

  public loopParentMaxMin(checkTask, task, laterChildId?, earlierChildId?) {
    let allTasks = this.allTasks;
    if (task.childTaskID.length > 0) {
      if (!laterChildId) {
        laterChildId = task.childTaskID[0];
      }
      if (!earlierChildId) {
        earlierChildId = task.childTaskID[0];
      }
      task.childTaskID.forEach((id) => {
        let child = allTasks[id - 1];
        let maxEndDate = allTasks[laterChildId - 1].endDate;
        let minStartDate = allTasks[earlierChildId - 1].startDate;
        if (child.childTaskID.length === 0) {
          if (moment(child.endDate).isAfter(maxEndDate)) {
            laterChildId = child.id;
          }
          if (moment(child.startDate).isBefore(minStartDate)) {
            earlierChildId = child.id;
          }
          checkTask.laterChildId = laterChildId;
          checkTask.earlierChildId = earlierChildId;
        } else {
          this.loopParentMaxMin(checkTask, child, laterChildId, earlierChildId);
        }
      });
    }
  }

  public loopActuralParentMaxMin(checkTask, task, acLaterChildId?, acEarlierChildId?) {
    let allTasks = this.allTasks;
    if (task.childTaskID.length > 0) {
      if (!acLaterChildId) {
        acLaterChildId = task.childTaskID[0];
      }
      if (!acEarlierChildId) {
        acEarlierChildId = task.childTaskID[0];
      }
      task.childTaskID.forEach((id) => {
        let child = allTasks[id - 1];
        let maxEndDate = allTasks[acLaterChildId - 1].actualEndDate;
        let minStartDate = allTasks[acEarlierChildId - 1].actualStartDate;
        if (child.childTaskID.length === 0) {
          if (moment(child.actualEndDate).isAfter(maxEndDate)) {
            acLaterChildId = child.id;
          }
          if (moment(child.actualStartDate).isBefore(minStartDate)) {
            acEarlierChildId = child.id;
          }
          checkTask.acLaterChildId = acLaterChildId;
          checkTask.acEarlierChildId = acEarlierChildId;
        } else {
          this.loopActuralParentMaxMin(checkTask, child, acLaterChildId, acEarlierChildId);
        }
      });
    }
  }

  public filterRelation(relation: PredecessorLinkModel[]) {
    let newArray: PredecessorLinkModel[] = [];
    relation.forEach((element) => {
      if (!element.isDelete) {
        newArray.push(element);
      }
    });
    return newArray;
  }

  /*
  *  根据前置任务计算allTasks的startDate
  */
  public updateStartDate = () => {
    // let relationsInfo = this.relationsInfo;
    let allTasks = this.allTasks;
    for (let i = 0; i < this.allTasks.length; i++) {
      let relation = this.allTasks[i].prevRelation;
      let task = allTasks[i];

      let ownPrevRelation = [];
      // 自己的前置任务relation
      relation.forEach((element) => {
        ownPrevRelation.push(element);
      });
      // 如果有父任务，加入父任务的relation
      if (task.parentTaskID) {
        this.parentLoop(ownPrevRelation, task);
      }
      // 计算最大的startDate
      let maxStartDate: any;
      // 筛选掉isDelete的relation
      ownPrevRelation = this.filterRelation(ownPrevRelation);
      if (ownPrevRelation.length > 0) {
        let truePrevTaskID;
        ownPrevRelation.forEach((relationInfo) => {
          let preTaskIndex = relationInfo.prevId - 1;
          let preTask = allTasks[preTaskIndex];
          let delay = relationInfo.delay;
          let duration = task.duration;
          let actualDuration = task.actualDuration;
          let startDate: any;
          let actualStartDate: any;
          let prevType = 1; // 1为普通任务，2为摘要任务
          if (!preTask) {
            console.log(preTask);
            console.log(task);
          }
          if (preTask.childTaskID.length > 0) {
            // 前置任务是摘要任务
            this.loopParentMaxMin(preTask, preTask);
            prevType = 2;
            let prevEndDate = allTasks[preTask.laterChildId - 1].endDate;
            let prevStartDate = allTasks[preTask.earlierChildId - 1].startDate;
            switch (relationInfo.relation) {
              // 完成-开始(FS)
              case PREVTYPE.FS:
                startDate = prevEndDate ? moment(prevEndDate).clone().add(1, 'days').toDate() : null;
                break;
              // 开始-开始(SS)
              case PREVTYPE.SS:
                startDate = prevStartDate ? moment(prevStartDate).clone().add(1, 'days').toDate() : null;
                break;
              // 完成-完成(FF)
              case PREVTYPE.FF:
                startDate = prevEndDate ? moment(prevEndDate).clone().subtract(duration - 1, 'days').toDate() : null;
                break;
              // 开始-完成(SF)
              case PREVTYPE.SF:
                startDate = prevStartDate ? moment(prevStartDate).clone().subtract(duration - 1, 'days').toDate() : null;
                break;
              default:
                return;
            }
          } else {
            prevType = 1;
            switch (relationInfo.relation) {
              // 完成-开始(FS)
              case PREVTYPE.FS:
                if (preTask.isMilepost && preTask.duration == 0) {
                  // 前置任务是里程碑,则startDate不加1
                  startDate = preTask.endDate ? moment(preTask.endDate).clone().add(delay, 'days').toDate() : null;
                } else {
                  // 前置任务是普通任务,则startDate加1
                  startDate = preTask.endDate ? moment(preTask.endDate).clone().add(delay + 1, 'days').toDate() : null;
                }
                break;
              // 开始-开始(SS)
              case PREVTYPE.SS:
                startDate = preTask.startDate ? moment(preTask.startDate).clone().add(delay, 'days').toDate() : null;
                break;
              // 完成-完成(FF)
              case PREVTYPE.FF:
                startDate = preTask.endDate ? moment(preTask.endDate).clone().add(delay, 'days').subtract(duration - 1, 'days').toDate() : null;
                break;
              // 开始-完成(SF)
              case PREVTYPE.SF:
                startDate = preTask.startDate ? moment(preTask.startDate).clone().add(delay, 'days').subtract(duration - 1, 'days').toDate() : null;
                break;
              default:
                return;
            }
          }
          // 第一次maxStartDate为null, 默认为第一个计算的startDate
          if (!maxStartDate) {
            maxStartDate = startDate;
            truePrevTaskID = prevType === 2 ? preTask.laterChildId : relationInfo.prevId;
          } else {
            if (moment(startDate).isAfter(maxStartDate)) {
              maxStartDate = startDate;
              truePrevTaskID = prevType === 2 ? preTask.laterChildId : relationInfo.prevId;
            }
          }
        });
        task.truePrevTaskID = truePrevTaskID;
        task.startDate = maxStartDate;
      } else {
        task.truePrevTaskID = null;
      }

      // 判断有没有受例外日期的影响
      let startUnix = task.startDate ? moment(task.startDate).unix() : null;
      let endUnix = task.endDate ? moment(task.endDate).unix() : null;
      // 先根据例外日期，改变任务的开始时间和结束时间
      this.exceptDate.forEach((item) => {
        // 任务开始时间在例外日期之间
        if (startUnix <= item.endDate && startUnix >= item.startDate) {
          let correctDate = moment.unix(item.endDate).clone().add(1, 'days').toDate();
          if (moment(correctDate).clone().isAfter(moment(maxStartDate))) {
            task.startDate = correctDate;
            // maxStartDate = correctDate;
          }
        }
        // 任务结束时间在例外日期之间
        if (endUnix <= item.endDate && endUnix >= item.startDate) {
          let correctDate = moment.unix(item.endDate).clone().add(1, 'days').toDate();
          task.endDate = correctDate;
        }
      });
    }
  }

  /*
  *  根据前置任务计算allTasks的startDate
  */
  // updateActualStartDate = () => {
  //   let relationsInfo = this.relationsInfo;
  //   let allTasks = this.allTasks;
  //   for (let i = 0; i < relationsInfo.length; i++) {
  //     let relation = relationsInfo[i];
  //     let task = allTasks[i];

  //     let ownPrevRelation = [];
  //     // 自己的relation
  //     relation.forEach(element => {
  //       ownPrevRelation.push(element)
  //     });
  //     // 如果有父任务，加入父任务的relation
  //     if (task.parentTaskID) {
  //       this.parentLoop(ownPrevRelation, task);
  //     }
  //     // 计算最大的startDate
  //     let maxStartDate: any;
  //     if (ownPrevRelation.length > 0 && task.finishRate === 0) {
  //       let truePrevTaskID;
  //       let actulaTruePrevTaskID;
  //       ownPrevRelation.forEach(relationInfo => {
  //         let preTaskIndex = relationInfo.prevId - 1;
  //         let preTask = allTasks[preTaskIndex];
  //         let delay = relationInfo.delay;
  //         let duration = task.duration;
  //         let actualDuration = task.actualDuration;
  //         let startDate: any;
  //         let actualStartDate: any;
  //         let prevType: number = 1; // 1为普通任务，2为摘要任务
  //         if (preTask.childTaskID.length > 0) {
  //           // 前置任务是摘要任务
  //           this.loopActuralParentMaxMin(preTask, preTask);
  //           prevType = 2;
  //           let prevEndDate = allTasks[preTask.acLaterChildId - 1].actualEndDate;
  //           let prevStartDate = allTasks[preTask.acEarlierChildId - 1].actualStartDate;
  //           switch (relationInfo.relation) {
  //             // 完成-开始(FS)
  //             case PREVTYPE.FS:
  //               actualStartDate = prevEndDate ? prevEndDate.clone().add(1, 'days').toDate() : null;
  //               break;
  //             // 开始-开始(SS)
  //             case PREVTYPE.SS:
  //               actualStartDate = prevStartDate ? prevStartDate.clone().add(1, 'days').toDate() : null;
  //               break;
  //             // 完成-完成(FF)
  //             case PREVTYPE.FF:
  //               actualStartDate = prevEndDate ? prevEndDate.clone().subtract(duration - 1, 'days').toDate() : null;
  //               break;
  //             // 开始-完成(SF)
  //             case PREVTYPE.SF:
  //               actualStartDate = prevStartDate ? prevStartDate.clone().subtract(duration - 1, 'days').toDate() : null;
  //               break;
  //             default:
  //               return;
  //           }
  //         } else {
  //           prevType = 1;
  //           switch (relationInfo.relation) {
  //             // 完成-开始(FS)
  //             case PREVTYPE.FS:
  //               if (preTask.isMilepost && preTask.duration == 0) {
  //                 // 前置任务是里程碑,则actualStartDate不加1
  //                 actualStartDate = preTask.actualEndDate ? moment(preTask.actualEndDate).clone().add(delay, 'days').toDate() : null;
  //               } else {
  //                 // 前置任务是普通任务,则actualStartDate加1
  //                 actualStartDate = preTask.actualEndDate ? moment(preTask.actualEndDate).clone().add(delay + 1, 'days').toDate() : null;
  //               }
  //               break;
  //             // 开始-开始(SS)
  //             case PREVTYPE.SS:
  //               actualStartDate = preTask.actualStartDate ? moment(preTask.actualStartDate).clone().add(delay, 'days').toDate() : null;
  //               break;
  //             // 完成-完成(FF)
  //             case PREVTYPE.FF:
  //               actualStartDate = preTask.actualEndDate ? moment(preTask.actualEndDate).clone().add(delay, 'days').subtract(duration - 1, 'days').toDate() : null;
  //               break;
  //             // 开始-完成(SF)
  //             case PREVTYPE.SF:
  //               actualStartDate = preTask.actualStartDate ? moment(preTask.actualStartDate).clone().add(delay, 'days').subtract(duration - 1, 'days').toDate() : null;
  //               break;
  //             default:
  //               return;
  //           }
  //         }
  //         // 第一次maxStartDate为null, 默认为第一个计算的startDate
  //         if (!maxStartDate) {
  //           maxStartDate = actualStartDate;
  //           actulaTruePrevTaskID = prevType === 2 ? preTask.acLaterChildId : relationInfo.prevId;
  //         } else {
  //           if (moment(actualStartDate).isAfter(maxStartDate)) {
  //             maxStartDate = actualStartDate;
  //             actulaTruePrevTaskID = prevType === 2 ? preTask.acLaterChildId : relationInfo.prevId;
  //           }
  //         }
  //       })
  //       if (maxStartDate) {
  //         task.actualStartDate = maxStartDate;
  //       }
  //       task.actulaTruePrevTaskID = actulaTruePrevTaskID;
  //     } else {
  //       task.actulaTruePrevTaskID = null;
  //     }

  //     // 判断有没有受例外日期的影响
  //     let startUnix = task.actualStartDate ? moment(task.actualStartDate).unix() : null;
  //     let endUnix = task.actualEndDate ? moment(task.actualEndDate).unix() : null;
  //     // 先根据例外日期，改变任务的开始时间和结束时间
  //     this.exceptDate.forEach(item => {
  //       // 任务开始时间在例外日期之间
  //       if (startUnix <= item.endDate && startUnix >= item.startDate) {
  //         let correctDate = moment.unix(item.endDate).clone().add(1, 'days').toDate();
  //         if (moment(correctDate).clone().isAfter(moment(maxStartDate))) {
  //           task.actualStartDate = correctDate;
  //           // maxStartDate = correctDate;
  //         }
  //       }
  //       // 任务结束时间在例外日期之间
  //       if (endUnix <= item.endDate && endUnix >= item.startDate) {
  //         let correctDate = moment.unix(item.endDate).clone().add(1, 'days').toDate();
  //         task.actualEndDate = correctDate;
  //       }
  //     });


  //   }
  // }

  /*
  * 计算左边虚表length
  */
  public resizeBarHandle(height: number) {
    // 50: toolbar高度
    this.taskShowLength = Math.ceil((height - 50) / this.taskHeight);
    this.updateAllTaskInfo();
  }

  /*
  * gantt假容器滚动--gantt
  */
  public scrollHandle(starIndex: number) {
    this.starIndex = starIndex;
    this.updateAllTaskInfo();
  }

  // Task展示计算(ngOnChange)
  public updateTaskHandle = () => {
    let startIndex = this.starIndex;
    let endIndex = this.starIndex + this.taskShowLength;

    if (this.allTasks && this.allTasks.length > 0) {
      let allTasks = this.getAllTaskAfterFold();
      this.showTask = allTasks.slice(startIndex, endIndex);
    } else {
      this.showTask = [];
    }
  }


  public getAllTaskAfterFold() {
    let allTasks = this.allTasks;
    let newAllTasks = [];
    let hideTasksId = [];
    allTasks.forEach((task, index) => {
      if (task.isFold) {
        for (let m = index + 1; m < allTasks.length; m++) {
          let element = allTasks[m];
          if (element.level > allTasks[index].level) {
            if (hideTasksId.indexOf(m + 1) === -1) {
              hideTasksId.push(element.id);
            } else {
              return;
            }
          } else {
            break;
          }
        }
      }
    });

    this.hideTasksId = hideTasksId;
    for (let i = 0; i < allTasks.length; i++) {
      const element = allTasks[i];
      if (hideTasksId.indexOf(element.id) == -1) {
        newAllTasks.push(element);
      }
    }
    return newAllTasks;
  }

  public ParentId2WBS(allTasks: any[], level) {
    let loopChild = (allTasks: any, level: number) => {
      let index = 1;
      for (let i = 0; i < allTasks.length; i++) {
        const element = allTasks[i];
        if (element.level == level) {
          let array = new Array;
          let parentTaskWBS = element.parentTaskID ? this.allTasks[element.parentTaskID - 1].wbs : [];
          parentTaskWBS.forEach((wbs) => {
            array.push(wbs);
          });
          array.push(index.toString());
          element.wbs = array;
          index++;
          if (element.childTaskID.length > 0) {
            let childTask = [];
            element.childTaskID.forEach((element) => {
              childTask.push(this.allTasks[element - 1]);
            });
            loopChild(childTask, level + 1);
          }
        }
      }
    };

    this.allTasks.forEach((ele) => {
      ele.wbs = [];
    });
    loopChild(allTasks, level);
    this.allTasks.forEach((ele) => {
      ele.wbs = ele.wbs.join('.');
    });
  }

  /**
   * 保存
   * @param type save:保存;submit:提交
   */
  public async saveTasksHanle(type: string) {
    let allTasks = this.allTasks;
    let taskHasSqlId = [];
    let alreadyAddTasks: GanttModel[] = [];
    let alreadyEditTasks: GanttModel[] = [];
    let alreadyDeleteTasks: GanttModel[] = this.alreadyDeleteTasks;
    this.loading = true;

    console.log("gantt.service.saveTaskHandle:allTasks",allTasks);
    this.ParentId2WBS(allTasks, 1);
    this.loading = false;


    // 组装 alreadyEditTasks
    allTasks.forEach((task) => {
      if (task.defaultData) {
        taskHasSqlId.push(task);
      } else {
        this.maxUID = this.maxUID + 1;
        task.uid = this.maxUID;
        alreadyAddTasks.push(task);
      }
    });

    // // 组装 alreadyEditTasks
    for (let i = 0; i < taskHasSqlId.length; i++) {
      const element = taskHasSqlId[i];
      let defaultData = element.defaultData;
      let dateKey = ['startDate', 'endDate', 'actualStartDate', 'actualEndDate'];
      let arrayKey = ['bindings', 'childTaskID', 'prevRelation'];
      for (let itemKey in defaultData) {
        if (element[itemKey] && itemKey != 'duration') {
          if (dateKey.indexOf(itemKey) != -1) {
            let elementDate = moment(element[itemKey]).format('YYYY MM DD');
            let defaultDate = moment(defaultData[itemKey]).format('YYYY MM DD');
            if (elementDate !== defaultDate) {
              let finder = alreadyEditTasks.findIndex((task) => {
                return task.sqId == element.sqId;
              });
              if (finder == -1) {
                alreadyEditTasks.push(element);
              }
            }
          } else if (arrayKey.indexOf(itemKey) != -1) {
            let elementArray = element[itemKey].toString();
            let defaultArray = defaultData[itemKey].toString();
            if (elementArray !== defaultArray) {
              let finder = alreadyEditTasks.findIndex((task) => {
                return task.sqId == element.sqId;
              });
              if (finder == -1) {
                alreadyEditTasks.push(element);
              }
            }
          } else {
            if (element[itemKey] != defaultData[itemKey]) {
              let finder = alreadyEditTasks.findIndex((task) => {
                return task.sqId == element.sqId;
              });
              if (finder == -1) {
                alreadyEditTasks.push(element);
              }
            }
          }
        }
      }
    }

    // 查询id是否连续
    let finder = allTasks.find((task, index) => {
      return task.id !== index + 1;
    });

    if (finder) {
      // 有错乱
      console.log(finder);
      this._message.error('orderId重复');
      this.loading = false;
    } else {
      let param = {
        add: alreadyAddTasks,
        update: alreadyEditTasks,
        drop: alreadyDeleteTasks,
        step: this.ganttStep
      };
      console.log(param);
      this.loading = false;
      let tasks = alreadyAddTasks.concat(alreadyEditTasks);
      console.log(this.dealwithPredecessorLink(tasks));
      // 整理
      let paramJson = [];
      alreadyAddTasks.forEach((task) => {
        paramJson.push({
          op: 'create',
          type: 'task',
          data: task.toMpp()
        });
      });
      alreadyEditTasks.forEach((task) => {
        paramJson.push({
          op: 'update',
          type: 'task',
          data: task.toMpp()
        });
      });
      alreadyDeleteTasks.forEach((sqid) => {
        paramJson.push({
          op: 'delete',
          type: 'task',
          data: { Id: sqid }
        });
      });
      console.log("alreadyEditTasks",alreadyEditTasks);
      let editPrev = this.dealwithPredecessorLink(tasks).editPrev;
      let deletePrev = this.dealwithPredecessorLink(tasks).deletePrev;
      let addPrev = this.dealwithPredecessorLink(tasks).addPrev;

      editPrev.forEach((prev) => {
        paramJson.push({
          op: 'update',
          type: 'link',
          data: prev
        });
      });
      deletePrev.forEach((prev) => {
        paramJson.push({
          op: 'delete',
          type: 'link',
          data: prev
        });
      });
      addPrev.forEach((prev) => {
        paramJson.push({
          op: 'create',
          type: 'link',
          data: prev
        });
      });
      // console.log(JSON.stringify(paramJson))
      console.log(paramJson);
      let res = await this.ganttRequestSev.putTasks(this.currentGantt.id, paramJson);
      if (res) {
        this._message.success('提交成功');
      } else {
        this._message.success('提交成功');
      }
      console.log(JSON.stringify(paramJson));

      // return this.submitTasksDatas(param).then(res => {
      //   if (res) {
      //     this.updateMilestoneRate();
      //     setTimeout(() => {
      //       // this.ganttServiceInit();
      //       this._message.success('保存成功');
      //     }, 500);
      //   } else {
      //     this._message.error('保存失败')
      //   }
      // })
    }
  }


  public dealwithPredecessorLink(tasks: GanttModel[]) {
    let editPrev = [];
    let addPrev = [];
    let deletePrev = [];
    for (let i = 0; i < tasks.length; i++) {
      const element = tasks[i];
      let relation = element.prevRelation;
      relation.forEach((prev) => {
        // 处理PredecessorLink
        if (prev.id && !prev.isDelete) {
          editPrev.push({
            PredecessorUID: this.allTasks[prev.prevId - 1].uid,
            ParentId: element.sqId,
            Type: prev.relation,
            LinkLag: prev.delay * 8 * 600,
            Id: prev.id
          });
        } else if (prev.id && prev.isDelete) {
          deletePrev.push({
            Id: prev.id
          });
        } else if (!prev.id && !prev.isDelete) {
          addPrev.push({
            PredecessorUID: this.allTasks[prev.prevId - 1].uid,
            ParentId: element.sqId,
            Type: prev.relation,
            LinkLag: prev.delay ? prev.delay * 8 * 600 : 0
          });
        }
      });
    }
    return {
      editPrev,
      addPrev,
      deletePrev
    };
  }

  /**
   * 提交保存数据
   * @param param
   */
  private submitTasksDatas(param: { add: Array<GanttModel>, update: Array<GanttModel>, drop: Array<number>, step: number }): Promise<boolean> {
    let jsonParam = {
      add: JSON.stringify(param.add),
      update: JSON.stringify(param.update),
      drop: JSON.stringify(param.drop),
      step: param.step
    };
    return this.requestClientService.post(this.addTaskList, jsonParam).then((res) => {
      console.log(res);
      if (res.code === 1) {
        return true;
      } else {
        return false;
      }
    });
  }

  /**
   * 插入，新增task
   * @param type
   */
  public addTaskHandle(type: string) {
    let createUUid = () => {
      let s = [];
      let hexDigits = "0123456789abcdef";
      for (let i = 0; i < 36; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
      }
      s[14] = "4";  // bits 12-15 of the time_hi_and_version field to 0010
      s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01
      s[8] = s[13] = s[18] = s[23] = "-";

      let uuid = s.join("");
      return uuid;
    };

    let allTasks = this.allTasks;
    let canvasInfo = this.canvasInfo;
    let firstSelectTask = allTasks.find(function (task, index) {
      return task.IsSelected == true;
    });
    let config = {
      taskName: '',
      isMilepost: false
    };
    if (type == 'milepost') {
      config.taskName = '里程碑',
        config.isMilepost = true;
    } else {
      config.taskName = '新建任务',
        config.isMilepost = false;
    }

    if (!firstSelectTask) {
      let newTask = new GanttModel({
        sqId: createUUid(),
        id: allTasks.length + 1,
        symbol: allTasks.length + 1000,
        ganttChartId: this.ganttChartId,
        taskName: config.taskName,
        IsSelected: false,
        startDate: null,
        duration: 0,
        endDate: null,
        actualStartDate: null,
        actualDuration: 0,
        actualEndDate: null,
        childTaskID: [],
        parentTaskID: null,
        isMilepost: config.isMilepost,
        level: firstSelectTask,
        bindings: [],
        prevRelation: [],
        finishRate: 0,
        exceptDate: this.exceptDate ? this.exceptDate : [],
        step: this.ganttStep
      });
      allTasks.push(newTask);
    } else {
      let firstSelectIndex = firstSelectTask.id - 1;
      let newTask = new GanttModel({
        sqId: createUUid(),
        id: firstSelectIndex + 1,
        symbol: allTasks.length + 1000,
        ganttChartId: this.ganttChartId,
        taskName: config.taskName,
        IsSelected: false,
        startDate: null,
        duration: 0,
        endDate: null,
        actualStartDate: null,
        actualDuration: 0,
        actualEndDate: null,
        childTaskID: [],
        parentTaskID: null,
        isMilepost: config.isMilepost,
        level: firstSelectTask.level,
        bindings: [],
        prevRelation: [],
        finishRate: 0,
        exceptDate: this.exceptDate ? this.exceptDate : [],
        step: this.ganttStep
      });
      allTasks.splice(firstSelectIndex, 0, newTask);
      for (let i = 0; i < allTasks.length; i++) {
        let relation = allTasks[i].prevRelation;
        relation.forEach((element) => {
          if (element.prevId > firstSelectIndex) {
            element.prevId = element.prevId + 1;
          }
        });
      }
    }

    console.log(this.allTasks);

    this.loopAllTasksId();
    // 涉及到两个数组
    // console.log(this.allTasks)
    // console.log(this.canvasInfo)
  }

  // stringToInt = (prevTask: string) => {
  //   let prevStringArry = [];
  //   let prevIntArry = [];
  //   if (prevTask) {
  //     prevStringArry = prevTask.split(",");
  //     for (let n = 0; n < prevStringArry.length; n++) {
  //       prevIntArry.push(parseInt(prevStringArry[n]))
  //     }
  //   }
  //   return prevIntArry
  // }

  /*
  * 删除任务
  */
  public deleteTaskHandle = () => {
    let allTasks = this.allTasks;
    let deleteTasks = [];
    let search = (element) => {
      if (element.childTaskID && element.childTaskID.length > 0) {
        element.childTaskID.forEach((childID) => {
          if (deleteTasks.indexOf(childID) == -1) {
            deleteTasks.push(childID);
          }
          search(allTasks[childID - 1]);
        });
      } else {
        return;
      }
    };

    // 拼装deleteTasks
    for (let i = 0; i < allTasks.length; i++) {
      const element = allTasks[i];
      const id = element.id;
      if (element.IsSelected) {
        deleteTasks.push(id);
        search(element);
        // allTasks.splice(id - 1, 1)
      }
    }

    // 将删除的task放在this.alreadyDeleteTasks中
    for (let i = 0; i < deleteTasks.length; i++) {
      const id = deleteTasks[i];
      let finder = allTasks.find((task) => {
        return task.id == id;
      });
      if (finder.sqId) {
        this.alreadyDeleteTasks.push(finder.sqId);
      }

    }

    // 将选中的tasks从allTasks移除
    for (let i = allTasks.length - 1; i >= 0; i--) {
      const id = allTasks[i].id;
      let find = deleteTasks.find((task, index) => {
        return task == id;
      });
      if (find) {
        allTasks.splice(find - 1, 1);
      }
    }

    // 循环删除任务的id数组
    for (let i = 0; i < allTasks.length; i++) {
      // 第一次循环，删除relation中已删除的任务对应的relation
      let prevRelation = allTasks[i].prevRelation;
      prevRelation.forEach((relation, index) => {
        if (deleteTasks.indexOf(relation.prevId) !== -1) {
          prevRelation.splice(index, 1);
        }
      });

      // 第二次循环,比删除任务id大的prevId-1
      for (let m = 0; m < prevRelation.length; m++) {
        let relation = prevRelation[m];
        let prevId = relation.prevId;
        let smallprev = [];
        deleteTasks.forEach((id) => {
          if (id < prevId) {
            smallprev.push(id);
          }
        });
        if (smallprev.length > 0) {
          prevId = prevId - smallprev.length;
          prevRelation[m].prevId = prevId;
        }
      }
    }
    this.loopAllTasksId();
  }


  /*
  * 循环重置allTasks的id
  * privat for delete & add function
  */
  public loopAllTasksId = () => {
    let allTasks = this.allTasks;
    for (let i = 0; i < allTasks.length; i++) {
      const element = allTasks[i];
      element.id = i + 1;
    }
    this.updateAllTaskInfo();
  }

  /*
  * 降级
  */
  public depressTaskLevel() {
    let selectTasks = this.checkSelectNumber();
    if (selectTasks) {
      // 拼装depressTasksId
      let search = (element, depressTasksId) => {
        if (element.childTaskID && element.childTaskID.length > 0) {
          element.childTaskID.forEach((childID) => {
            if (depressTasksId.indexOf(childID) == -1) {
              depressTasksId.push(childID);
            }
            search(this.allTasks[childID - 1], depressTasksId);
          });
        } else {
          return;
        }
      };
      selectTasks.forEach((task) => {
        // 任务leve + 1
        let depressTasksId = [];
        depressTasksId.push(task.id);
        search(task, depressTasksId);
        depressTasksId.forEach((id) => {
          let upperTask = this.allTasks[id - 2];
          if (this.allTasks[id - 1].level > upperTask.level) {
            return;
          } else {
            this.allTasks[id - 1].level = this.allTasks[id - 1].level + 1;
          }
        });
        // let id = task.id;
        // let upperTask = this.allTasks[id - 2];
        // if (task.level > upperTask.level) {
        //   return;
        // } else {
        //   task.level = task.level + 1;
        // }
      });
    }

    this.updateAllTaskInfo();
  }

  /*
  * 升级
  */
  public promoteTaskLevel() {
    let selectTasks = this.checkSelectNumber();

    if (selectTasks) {
      // 拼装promoteTasksId
      let search = (element, promoteTasksId) => {
        if (element.childTaskID && element.childTaskID.length > 0) {
          element.childTaskID.forEach((childID) => {
            if (promoteTasksId.indexOf(childID) == -1) {
              promoteTasksId.push(childID);
            }
            search(this.allTasks[childID - 1], promoteTasksId);
          });
        } else {
          return;
        }
      };

      selectTasks.forEach((task) => {
        let promoteTasksId = [];
        // 任务leve + 1
        promoteTasksId.push(task.id);
        search(task, promoteTasksId);
        promoteTasksId.forEach((id) => {
          if (this.allTasks[id - 1].level > 1) {
            this.allTasks[id - 1].level = this.allTasks[id - 1].level - 1;
          }
        });
      });
    }

    this.updateAllTaskInfo();
  }

  /*
  * 更新levelInfo
  * 根据level计算childTaskID和parentTaskID
  * major fuction
  */
  public updateLeveInfo() {
    let allTasks = this.allTasks;
    allTasks.forEach((element) => {
      element.childTaskID = [];
      element.parentTaskID = null;
    });
    // 计算所有任务的childTaskID和parentTaskID
    allTasks.forEach((task, index) => {
      let nextIndex = index + 1;
      this.levelLoop(allTasks, task, nextIndex);
    });

    // 降级后，子任务的前置任务变成了它的父任务，则移除该前置任务
    for (let i = 0; i < allTasks.length; i++) {
      const element = allTasks[i];
      let childrenId = allTasks[i].childTaskID;
      childrenId.forEach((id) => {
        if (!allTasks[id - 1]) {
          console.log(id);
        }
        this.removeParentID(allTasks[id - 1], element.id);
      });
    }
  }

  /*
  * private for updateLeveInfo
  */
  public levelLoop(allTasks, task, nextIndex) {
    let level = task.level;
    if (allTasks[nextIndex] && allTasks[nextIndex].level > level) {
      if (allTasks[nextIndex].level == level + 1) {
        task.childTaskID.push(allTasks[nextIndex].id);
        allTasks[nextIndex].parentTaskID = task.id;
      }
      nextIndex++;
      this.levelLoop(allTasks, task, nextIndex);
    } else {
      return;
    }
  }


  /*
  * private for updateLeveInfo
  */
  public removeParentID = (children: GanttModel, parentId: number) => {
    let childArray = children.prevRelation;
    if (childArray && childArray.length > 0) {
      let check = childArray.findIndex((relation) => {
        return relation.prevId == parentId;
      });
      if (check !== -1) {
        childArray.splice(check, 1);
      }
      if (children.childTaskID.length != 0) {
        for (let i = 0; i < children.childTaskID.length; i++) {
          const element = this.allTasks[children.childTaskID[i] - 1];
          this.removeParentID(element, parentId);
        }
      }
    } else {
      return;
    }
  }

  /*
  * 获取选中任务数组
  * public for all fuction
  */
  public checkSelectNumber = () => {
    let allTasks = this.allTasks;
    let selectNumber = [];
    allTasks.forEach((element) => {
      if (element.IsSelected) {
        selectNumber.push(element);
      }
    });

    if (selectNumber.length > 0) {
      // this.createNotification('error', '请选择一个任务', 'large', '请检查');
      return selectNumber;
    } else {
      this.createNotification('error', '请选择一个任务', 'large', '请检查');
      return;
    }
  }

  /*
  * 计算摘要任务的开始时间和结束时间
  * major fuction
  */
  public updateParentStartDate = () => {
    let allTasks = this.allTasks;
    for (let i = allTasks.length - 1; i >= 0; i--) {
      if (allTasks[i].childTaskID.length > 0) {
        let parentTask = allTasks[i];
        this.loopParentMaxMin(parentTask, parentTask);
        let minStartDate = allTasks[parentTask.earlierChildId - 1].startDate;
        let maxEndDate = allTasks[parentTask.laterChildId - 1].endDate;
        this.allTasks[i].startDate = minStartDate;
        this.allTasks[i].endDate = maxEndDate;
      }
    }
    // for (let i = allTasks.length - 1; i >= 0; i--) {
    //   if (allTasks[i].childTaskID.length > 0) {
    //     // 清除parentTask绑定的构件
    //     // parentTask.bindings = [];
    //     // 计算parentTask的startDate和endDate
    //     // let maxEndDate = allTasks[parentTask.childTaskID[0] - 1].endDate;
    //     // let minStartDate = allTasks[parentTask.childTaskID[0] - 1].startDate;
    //     // for (let m = 0; m < parentTask.childTaskID.length; m++) {
    //     //   const child = parentTask.childTaskID[m];
    //     //   if (moment(allTasks[child - 1].endDate).isAfter(maxEndDate)) {
    //     //     maxEndDate = allTasks[child - 1].endDate;
    //     //   }
    //     //   if (moment(allTasks[child - 1].startDate).isBefore(minStartDate)) {
    //     //     minStartDate = allTasks[child - 1].startDate;
    //     //   }
    //     // }
    //     // this.allTasks[i].startDate = minStartDate;
    //     // this.allTasks[i].endDate = maxEndDate;
    //     // this.allTasks[i].laterChildId = laterChildId;
    //   }
    // }


  }

  /*
  * 计算摘要任务的实际开始时间和结束时间
  * major fuction
  */
  public updateParentActualStartDate = () => {
    let allTasks = this.allTasks;
    for (let i = allTasks.length - 1; i >= 0; i--) {
      if (allTasks[i].childTaskID.length > 0) {
        let parentTask = allTasks[i];
        this.loopActuralParentMaxMin(parentTask, parentTask);
        let minStartDate = allTasks[parentTask.acEarlierChildId - 1].actualStartDate;
        let maxEndDate = allTasks[parentTask.acLaterChildId - 1].actualEndDate;
        this.allTasks[i].actualStartDate = minStartDate;
        this.allTasks[i].actualEndDate = maxEndDate;
      }
    }
  }



  /*
  * 绑定构件
  */
  public async bingdingGUID(isFirstBind: boolean) {
    let uuids: string[];
    let selectTasks = this.checkSelectNumber();
    let ganttId = this.currentGantt.id;
    let taskId = selectTasks[0].sqId;
    let extendAttrs = await this.ganttRequestSev.getTaskAttrs(ganttId, taskId);
    console.log(extendAttrs)
    let finder = extendAttrs.find((attr) => {
      return attr.fieldID == EXTENDATTRS.binding.FieldID;
    });
    if (isFirstBind) {
      uuids = this.ganttApi.getSelectedUUIDs();
      console.log(uuids);
      selectTasks[0].bindings = [];
    } else {
      // 追加构件
      uuids = this.ganttApi.addOver();
    }
    if (uuids.length == 0) {
      this.createNotification('error', '请选择构件', 'small');
    } else {
      let bindings = selectTasks[0].bindings;
      if (selectTasks.length !== 1) {
        this.createNotification('error', '请选择单个任务绑定构件', 'small');
      } else {
        // selectTasks[0].bindings = uuid;
        uuids.forEach((uid) => {
          bindings.push(new UInfoModel({
            uuid: gum.btoa(uid),
            isFinished: false
          })
          );
        });
        if (!finder) {
          let param = {
            FieldID: EXTENDATTRS.binding.FieldID,
            Value: JSON.stringify(bindings)
          };
          let res = this.ganttRequestSev.bindTaskExtendedAttribute(ganttId, taskId, param);
          if (res) {
            this._message.success('绑定成功');
          } else {
            this._message.success('绑定失败');
          }
        } else {
          let param = {
            Value: JSON.stringify(bindings)
          };
          let res = await this.ganttRequestSev.updateExtendedAttrbute(ganttId, taskId, finder.id, param);
          if (res) {
            this._message.success('更新绑定成功');
          } else {
            this._message.success('更新绑定失败');
          }
        }
        let symbol = selectTasks[0].symbol;
        this.uuidMap.set(symbol, bindings);
        this.showBindings(symbol);
      }
      // this.createNotification('success', '绑定成功', 'small')
    }
  }

  /*
  * 解绑构件
  */
  public async unbingdingGUID() {
    let selectTasks = this.checkSelectNumber();
    let ganttId = this.currentGantt.id;

    selectTasks.forEach(async (element) => {
      let extendAttrs = await this.ganttRequestSev.getTaskAttrs(ganttId, element.sqId);
      let finder = extendAttrs.find((attr) => {
        return attr.fieldID == EXTENDATTRS.binding.FieldID;
      });
      let param = {
        Value: JSON.stringify([])
      };
      let res = await this.ganttRequestSev.updateExtendedAttrbute(ganttId, element.sqId, finder.id, param);
      if (res) {
        this._message.success('解绑成功');
        element.bindings = [];
        element.finishRate = 0;
        this.ganttApi.home3D();
      } else {
        this._message.success('解绑失败');
      }
    });

    // this.modelService.selectFloorShow()
    this.ganttApi.clearSelectedUUIDS();
  }

  /*
  * 全选
  */
  public selectAllTask() {
    let allTasks = this.allTasks;
    let allSelected = this.IsAllSelected;
    if (allSelected) {
      allTasks.forEach((element) => {
        element.IsSelected = true;
      });
    } else {
      allTasks.forEach((element) => {
        element.IsSelected = false;
      });
    }

    this.updateAllTaskInfo();
  }

  /*
  * 点选taskName
  */
  public clickTaskName(task: GanttModel) {
    task.IsSelected = !task.IsSelected;
    let allTasks = this.allTasks;
    allTasks.forEach((ele) => {
      if (ele.id !== task.id) {
        ele.IsSelected = false;
      }
    });

    if (task.IsSelected) {
      console.log(task);
      this.currentTask = task;
      this.detailView = true;
      this.loopShowBindings(task);
    } else {
      this.detailView = false;
      this.cancelshowBindings();
    }
    this.updateCanvasInfo();
  }

  public loopShowBindings(task: GanttModel) {
    if (task.bindings.length > 0) {
      this.showBindings(task.symbol);
    } else {
      if (task.level > 1) {
        let parentTask = this.allTasks[task.parentTaskID - 1];
        this.loopShowBindings(parentTask);
      } else {
        this.cancelshowBindings();
      }
    }
  }

  /*
  * 点选checkbox
  */
  public clickCheckBox(task: GanttModel) {
    // 选中
    // if (task.IsSelected) {
    //   // this.taskSelect(task)
    // } else {
    //   this.taskUnSelelct()
    // }
    let allTasks = this.allTasks;
    let selectTasks = [];
    allTasks.forEach((ele) => {
      if (ele.IsSelected) {
        selectTasks.push(ele);
      }
    });
    let symbols = [];

    allTasks.forEach((ele) => {
      if (ele.IsSelected && ele.bindings.length > 0) {
        symbols.push(ele.symbol);
      }
    });

    // if (symbols.length > 0) {
    //   this.showBindings(symbols);
    // } else {
    //   this.cancelshowBindings()
    // }
    this.updateCanvasInfo();
  }

  /*
  * private for clickTaskName & clickCheckBox
  */
  public taskSelect(task: GanttModel) {
    let allTasks = this.allTasks;
    allTasks.forEach((element) => {
      element.IsSelected = false;
    });
    if (task.childTaskID.length > 0) {
      let symbols = new Array();
      this.loopChildTask(task, symbols, true);
      // 如果是父任务,没有绑定,没有解绑,没有追加
      this.bindingsControll = {
        addBindingsShow: false,
        removeBindsShow: false,
        addFragmentShow: false
      };
      if (symbols.length > 0) {
        this.showBindings(symbols);
      } else {
        this.cancelshowBindings();
      }
    } else {
      if (task.bindings && task.bindings.length > 0) {
        // 如果是子任务,且绑定了构件,没有绑定,有解绑,有追加
        this.bindingsControll = {
          addBindingsShow: false,
          removeBindsShow: true,
          addFragmentShow: true
        };
        this.showBindings(task.symbol);
      } else {
        // 如果是里程碑，没有绑定,没有解绑,没有追加
        if (task.isMilepost) {
          this.bindingsControll = {
            addBindingsShow: false,
            removeBindsShow: false,
            addFragmentShow: false
          };
        } else {
          // 如果是子任务,没构件,有绑定,没有解绑,没有追加
          this.bindingsControll = {
            addBindingsShow: true,
            removeBindsShow: false,
            addFragmentShow: false
          };
        }
        this.cancelshowBindings();
      }
      task.IsSelected = true;
    }
  }

  /*
  * private for clickTaskName & clickCheckBox
  */
  public taskUnSelelct() {
    let allTasks = this.allTasks;
    allTasks.forEach((element) => {
      element.IsSelected = false;
    });
    // 没有任务选中,有绑定,没有解绑,没有追加
    this.bindingsControll = {
      addBindingsShow: true,
      removeBindsShow: false,
      addFragmentShow: false
    };
    this.cancelshowBindings();
  }

  /*
  * private for clickTaskName & clickCheckBox
  */
  public loopChildTask(parent: GanttModel, symbols: number[], IsSelected: boolean) {
    let childArray = parent.childTaskID;
    parent.IsSelected = IsSelected;
    if (childArray.length > 0) {
      childArray.forEach((chidId) => {
        let child = this.allTasks[chidId - 1];
        child.IsSelected = IsSelected;
        if (child.bindings && child.bindings.length > 0) {
          let symbol = this.allTasks[chidId - 1].symbol;
          symbols.push(symbol);
        }
        this.loopChildTask(this.allTasks[chidId - 1], symbols, IsSelected);
      });
    } else {
      return;
    }
  }

  /*
  * private for clickTaskName & clickCheckBox
  */
  public showBindings(symbol) {
    console.log(this.uuidMap.get(symbol));
    let unFinish = [];
    this.uuidMap.get(symbol).forEach((element) => {
      if (element.isFinished == 0) {
        unFinish.push(element.uuid);
      }
    });
    this.ganttApi.renderUuid(unFinish);
  }

  /*
  * private for clickTaskName & clickCheckBox
  */
  public cancelshowBindings() {
    // this.modelService.cancelshowBindings()
    this.ganttApi.home3D();
  }

  /*
  * 提交进度的milestone
  */
  public updateMilestoneRate() {
    let allTasks = this.allTasks;
    let mileposts = [];
    let milestone = [];   //传给接口的参数
    // 里程碑数组
    allTasks.forEach((element) => {
      if (element.isMilepost) {
        mileposts.push(element);
      }
    });
    let finishRates = [];

    if (mileposts.length > 0) {
      mileposts.forEach((task, index) => {
        let group = [];
        if (index === 0) {
          group = allTasks.slice(0, task.id - 1);
        } else {
          let prevIndex = mileposts[index - 1].id - 1;
          group = allTasks.slice(prevIndex, task.id - 1);
        }
        let finishRate = 0;
        group.forEach((task) => {
          finishRate = finishRate + task.finishRate;
        });
        let num = finishRate / (group.length * 100);
        finishRates.push(Math.round(num * 100));
      });
      mileposts.forEach((value, index) => {
        milestone.push({
          name: value.taskName,
          rate: finishRates[index]
        });
      });
    } else {
      let finishRate = 0;
      allTasks.forEach((task) => {
        finishRate = finishRate + task.finishRate;
      });
      let num = finishRate / (allTasks.length * 100);
      // finishRates.push(Math.round(num * 100));

      milestone.push({
        name: '总进度',
        rate: Math.round(num * 100)
      });
    }

    // 更新ganttChart的milestone
    let param = {
      id: this.ganttChartId,
      milestone: JSON.stringify(milestone)
    };
    console.log(param);
    this.requestClientService.post(SERVERURL + `api/gantt/update`, param).then((res) => {
      if (res.code == 1) {
        this.createNotification('success', '成功更新milestone', 'small');
      } else {
        console.log(res);
      }
    });
  }

  /*
  * 更改工作安排id
  */
  public changePlanning() {
    //更新project的工作安排id
    let projectId = JSON.parse(window.localStorage.getItem('project')).id;
    let projectParam = {
      id: projectId,
      planToGanttChartId: parseInt(this.ganttChartId)
    };
    console.log(projectParam);
    this.requestClientService.post(SERVERURL + `api/project/changeNormalAttr`, projectParam).then((res) => {
      if (res.code == 1) {
        this.createNotification('success', '成功设置工作安排', 'small');
        // this.menuService.planningId = this.ganttChartId;
      } else {
        console.log(res);
      }
    });
  }

  /**
 * 更新进度
 * @param param
 */
  public updateGanttInfo(param): Promise<boolean> {
    return this.requestClientService.post(SERVERURL + `api/gantt/update`, param).then((res) => {
      console.log(res);
      if (res.code === 1) {
        return true;
      } else {
        return false;
      }
    });
  }

}
